#include "drv_uart.h"
#include "drv_led.h"

const int UART1RX_BUF_MAX = 1024;
const int UART1TX_BUF_MAX = 1024;
const int UART2RX_BUF_MAX = 1024;
const int UART2TX_BUF_MAX = 1024;
const int UART3RX_BUF_MAX = 1024;
const int UART3TX_BUF_MAX = 1024;
const int UART4RX_BUF_MAX = 1024;
const int UART4TX_BUF_MAX = 1024;

extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart3;

__IO static uint8_t Uart1TxDone = SET;
__IO static uint8_t Uart1RxDone = RESET;
__IO static uint32_t Uart1TxLen = 0;
__IO static uint32_t Uart1RxLen = 0;
__IO static uint8_t Uart1TxBuffer[UART1TX_BUF_MAX] = {0};
__IO static uint8_t Uart1RxBuffer[UART1RX_BUF_MAX] = {0};

//__IO bool gMPTest_Mode = false;


__IO static uint8_t Uart2TxBuffer[UART2TX_BUF_MAX] = {0};
__IO static uint8_t Uart2RxBuffer[UART2RX_BUF_MAX] = {0};

__IO static uint8_t Uart3TxDone = SET;
__IO static uint8_t Uart3RxDone = RESET;
__IO static uint32_t Uart3TxLen = 0;
__IO static uint32_t Uart3RxLen = 0;
__IO static uint8_t Uart3TxBuffer[UART3TX_BUF_MAX] = {0};
__IO static uint8_t Uart3RxBuffer[UART3RX_BUF_MAX] = {0};

__IO static uint8_t Uart4TxBuffer[UART4TX_BUF_MAX] = {0};
__IO static uint8_t Uart4RxBuffer[UART4RX_BUF_MAX] = {0};


//////////////////////////////////////////////////////////////////
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{ 	
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
	USART1->DR = (u8) ch;      
	return ch;
}
#endif

void drv_uart_user_init(void)
{
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart1, Uart1RxBuffer, UART1RX_BUF_MAX); 

	__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart3, Uart3RxBuffer, UART3RX_BUF_MAX); 
}

int drv_uart1_send_buffer(uint8_t *buffer, int length)
{
	int timeout = 0;
	
    if(length>UART1TX_BUF_MAX){
        length = UART1TX_BUF_MAX;
    }
	while (Uart1TxDone == RESET && timeout++ < 10)
		delayms(10);
    memcpy((uint8_t *)Uart1TxBuffer, buffer, length);
    if(HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Uart1TxBuffer, length) == HAL_OK){
        Uart1TxDone = RESET;
        return 1;
    }
    return 0;
}

int drv_uart1_Printf(const char *fmt, ...)
{
	int size = 0;
	int timeout = 0;
	va_list ap;
	while (Uart1TxDone == RESET && timeout++ < 10)
		delayms(10);
	va_start(ap, fmt);
	size = vsnprintf((char *)Uart1TxBuffer, UART1TX_BUF_MAX, fmt, ap);
	va_end(ap);
	if (size < 0 || size > UART1TX_BUF_MAX - 1)
		return -1;
    if(HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Uart1TxBuffer, size) == HAL_OK)
    {
        Uart1TxDone = RESET;
        return 1;
    }
	return size;
}


int drv_uart3_send_buffer(uint8_t *buffer, int length)
{
    if(length>UART3TX_BUF_MAX){
        length = UART3TX_BUF_MAX;
    }
    memcpy(Uart3TxBuffer, buffer, length);
    if(HAL_UART_Transmit(&huart3, (uint8_t *)Uart3TxBuffer, length, 100) == HAL_OK){
        return 1;
    }
    return 0;
}

int drv_uart3_Printf(const char *fmt, ...)
{
	int size = 0;
	int timeout = 0;
	va_list ap;
	while (Uart3TxDone == RESET && timeout++ < 10)
		delayms(10);
	va_start(ap, fmt);
	size = vsnprintf((char *)Uart3TxBuffer, UART3TX_BUF_MAX, fmt, ap);
	va_end(ap);
	if (size < 0 || size > UART3TX_BUF_MAX - 1)
		return -1;
    if(HAL_UART_Transmit_DMA(&huart3, (uint8_t *)Uart3TxBuffer, size) == HAL_OK){
        Uart3TxDone = RESET;
        return 1;
    }
	return size;
}



void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)
{
	if(huart->Instance == USART1){
    	Uart1TxDone = SET;
	}
	else if(huart->Instance == USART3){
    	Uart3TxDone = SET;
	}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)
{

}

void uart3_process(uint8_t *buf, uint32_t len)
{
	drv_ringbuf_write(buf, len);
}


void UART_IDLE_Callback(UART_HandleTypeDef * huart)
{
	uint32_t tmp1, tmp2;
	tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE);
	tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE); //获取IDLE标志位
	
	if((tmp1 != RESET)  && (tmp2 != RESET)){  //idle标志被置位
		__HAL_UART_CLEAR_IDLEFLAG(huart);//清除标志位
		tmp1 = huart->Instance->SR;//清除状态寄存器SR,读取SR可以清楚该寄存器
		tmp1 = huart->Instance->DR;//读取数据寄存器中的数据,读取DR
		HAL_UART_DMAStop(huart);
		/* Process Unlocked */
    	__HAL_UNLOCK(huart->hdmarx);
	 
	    if(huart->Instance == USART1){
	      Uart1RxLen = UART1RX_BUF_MAX - huart->hdmarx->Instance->NDTR;
	      HAL_UART_Receive_DMA(huart, Uart1RxBuffer, UART1RX_BUF_MAX);
	      Uart1RxDone = SET;
		  drv_led_trigger(2);
	    }
		else if(huart->Instance == USART3){
	      Uart3RxLen = UART3RX_BUF_MAX - huart->hdmarx->Instance->NDTR;
		  uart3_process(Uart3RxBuffer, Uart3RxLen);
	      HAL_UART_Receive_DMA(huart, Uart3RxBuffer, UART3RX_BUF_MAX);
	      Uart3RxDone = SET;
		  drv_led_trigger(3);
	    }
		/* set uart state  ready*/
		huart->gState = HAL_UART_STATE_READY;
	}
}


void uart_process(void)
{
	if(Uart1RxDone == SET){
		Uart1RxDone = RESET;
		//drv_uart1_send_buffer(Uart1RxBuffer, Uart1RxLen);
		drv_uart3_send_buffer(Uart1RxBuffer, Uart1RxLen);
	}
	else if(Uart3RxDone == SET){
		Uart3RxDone = RESET;
		//drv_uart3_send_buffer(Uart3RxBuffer, Uart3RxLen);
		drv_uart1_send_buffer(Uart3RxBuffer, Uart3RxLen);
	}
}

